//this file define Scanner class

#ifndef SCANNER_H
#define SCANNER_H

#include "GTpl/GMap.h"
#include "GIOStream.h"
#include "TINYToken.h"

class TINYScanner
{
public:
    TINYScanner();
    TINYScanner(GIOStream* io);
    ~TINYScanner();

    TINYToken* getToken();

private:
    void scan();

    bool getCharactor(char& ch);
    bool ungetCharactor(const char& ch);

    char m_ch;

    GIOStream* m_chIO;
    TINYToken* m_currentToken;

private:
    /*****************************begin state pattern classes**************************/
    class TINYScanState
    {
    public:
        virtual ~TINYScanState();

        virtual void scan(TINYScanner* scanner) = 0;

    protected:
        TINYScanState();

        void changeState(TINYScanner* scanner, TINYScanState* state);
    };

    void changeState(TINYScanState* state);

    TINYScanState* m_currentState;

    //------------------------start state declare---------------------------------------

    class TINYScanStartState : public TINYScanState
    {
    public:
        ~TINYScanStartState();

        static TINYScanStartState& instance();

        void scan(TINYScanner *scanner);

    private:
        TINYScanStartState();
        static TINYScanStartState _startState;
    };

    //------------------------incomment state declare---------------------------------------

    class TINYInCommentState : public TINYScanState
    {
    public:
        ~TINYInCommentState();

        static TINYInCommentState& instance();

        void scan(TINYScanner *scanner);

    private:
        TINYInCommentState();
        static TINYInCommentState _commentState;
    };

    //-----------------------inassign state declare---------------------------------------

    class TINYInAssignState : public TINYScanState
    {
    public:
        ~TINYInAssignState();

        static TINYInAssignState& instance();

        void scan(TINYScanner *scanner);

    private:
        TINYInAssignState();
        static TINYInAssignState _assignState;
    };

    //-----------------------innumber state declare-----------------------------------------

    class TINYInNumberState : public TINYScanState
    {
    public:
        ~TINYInNumberState();

        static TINYInNumberState& instance();

        void scan(TINYScanner *scanner);

    private:
        TINYInNumberState();
        static TINYInNumberState _numberState;
    };

    //-----------------------inid state declare-----------------------------------------------

    class TINYInIDState : public TINYScanState
    {
    public:
        ~TINYInIDState();

        static TINYInIDState& instance();

        void scan(TINYScanner *scanner);

    private:
        TINYInIDState();
        static TINYInIDState _idState;
    };
};



#endif // SCANNER_H
